Once the VMID is marked unused, a new domain can reuse the VMID for its
own. If the TLB is not flushed, entries can contain wrong translation.
When a new p2m is allocated, switch to the new VMID and flush TLB on
every physical CPUs.
Signed-off-by: Julien Grall <julien.grall@linaro.org>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
d->arch.vttbr = page_to_maddr(p2m->first_level)
| ((uint64_t)p2m->vmid&0xff)<<48;
+ p2m_load_VTTBR(d);
+
+ /* Make sure that all TLBs corresponding to the new VMID are flushed
+ * before using it
+ */
+ flush_tlb();
+
+ p2m_load_VTTBR(current->domain);
+
spin_unlock(&p2m->lock);
return 0;
spin_lock(&vmid_alloc_lock);
if ( p2m->vmid != INVALID_VMID )
clear_bit(p2m->vmid, vmid_mask);
+
spin_unlock(&vmid_alloc_lock);
}
isb();
}
+/* Flush inner shareable TLBs, current VMID only */
+static inline void flush_tlb(void)
+{
+ dsb();
+
+ WRITE_CP32((uint32_t) 0, TLBIALLIS);
+
+ dsb();
+ isb();
+}
+
/* Flush local TLBs, all VMIDs, non-hypervisor mode */
static inline void flush_tlb_all_local(void)
{
: : : "memory");
}
+/* Flush innershareable TLBs, current VMID only */
+static inline void flush_tlb(void)
+{
+ asm volatile(
+ "dsb sy;"
+ "tlbi vmalle1is;"
+ "dsb sy;"
+ "isb;"
+ : : : "memory");
+}
+
/* Flush local TLBs, all VMIDs, non-hypervisor mode */
static inline void flush_tlb_all_local(void)
{